From a45a1c42f64b76c3128fb76b3353628e9af0c6c2 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 23 Jul 2004 13:10:03 +0000 Subject: [PATCH] bitkeeper revision 1.1108.1.16 (41010e2br7ouRoQI0b4MbAxS1GzgpA) Allow specification of the domain id to use for a new domain. --- tools/libxc/xc_domain.c | 1 + tools/python/xen/lowlevel/xc/xc.c | 9 +- xen/common/dom0_ops.c | 115 +++++++++++++++++++++++--- xen/include/hypervisor-ifs/dom0_ops.h | 4 +- 4 files changed, 112 insertions(+), 17 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index ab83d0ce7b..838418e0b7 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -18,6 +18,7 @@ int xc_domain_create(int xc_handle, dom0_op_t op; op.cmd = DOM0_CREATEDOMAIN; + op.u.createdomain.domain = (domid_t)*pdomid; op.u.createdomain.memory_kb = mem_kb; strncpy(op.u.createdomain.name, name, MAX_DOMAIN_NAME); op.u.createdomain.name[MAX_DOMAIN_NAME-1] = '\0'; diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 3ee75db7da..6e55853360 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -44,13 +44,13 @@ static PyObject *pyxc_domain_create(PyObject *self, unsigned int mem_kb = 0; char *name = "(anon)"; int cpu = -1; - u32 dom; + u32 dom = 0; int ret; - static char *kwd_list[] = { "mem_kb", "name", "cpu", NULL }; + static char *kwd_list[] = { "dom", "mem_kb", "name", "cpu", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|isi", kwd_list, - &mem_kb, &name, &cpu) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iisi", kwd_list, + &dom, &mem_kb, &name, &cpu) ) return NULL; if ( (ret = xc_domain_create(xc->xc_handle, mem_kb, name, cpu, &dom)) < 0 ) @@ -927,6 +927,7 @@ static PyMethodDef pyxc_methods[] = { (PyCFunction)pyxc_domain_create, METH_VARARGS | METH_KEYWORDS, "\n" "Create a new domain.\n" + " dom [int, 0]: Domain identifier to use (allocated if zero).\n" " mem_kb [int, 0]: Memory allocation, in kilobytes.\n" " name [str, '(anon)']: Informative textual name.\n\n" "Returns: [int] new domain identifier; -1 on error.\n" }, diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 3af08f0731..c1f5486908 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -27,6 +27,98 @@ extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int); extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op); extern void arch_getdomaininfo_ctxt(struct domain *, full_execution_context_t *); +static inline int is_free_domid(domid_t dom) +{ + struct domain *d; + + if (dom >= DOMID_SELF) return 0; + d = find_domain_by_id(dom); + if (d == NULL) { + return 1; + } else { + put_domain(d); + return 0; + } +} + +/** Allocate a free domain id. We try to reuse domain ids in a fairly low range, + * only expanding the range when there are no free domain ids. This is to + * keep domain ids in a range depending on the number that exist simultaneously, + * rather than incrementing domain ids in the full 32-bit range. + */ +static int allocate_domid(domid_t *pdom) +{ + static spinlock_t domid_lock = SPIN_LOCK_UNLOCKED; + static domid_t curdom = 0; + static domid_t topdom = 101; + int err = 0; + domid_t cur, dom, top; + + /* Try to use a domain id in the range 0..topdom, starting at curdom. */ + spin_lock(&domid_lock); + cur = curdom; + dom = curdom; + top = topdom; + spin_unlock(&domid_lock); + do { + ++dom; + if (dom == top) { + dom = 1; + } + if (is_free_domid(dom)) goto exit; + } while (dom != cur); + /* Couldn't find a free domain id in 0..topdom, try higher. */ + for (dom = top; dom < DOMID_SELF; dom++) { + if(is_free_domid(dom)) goto exit; + } + /* No free domain ids. */ + err = -ENOMEM; + exit: + if (err == 0) { + spin_lock(&domid_lock); + curdom = dom; + if (dom >= topdom) { + topdom = dom + 1; + } + spin_unlock(&domid_lock); + *pdom = dom; + } + return err; +} + +#if 0 + struct domain *d; + static domid_t domnr = 0; + static spinlock_t domnr_lock = SPIN_LOCK_UNLOCKED; + unsigned int pro; + domid_t dom; + + ret = -ENOMEM; + + if(op->u.createdomain.domain > 0){ + d = find_domain_by_id(dom); + if(d){ + put_domain(d); + ret = -EINVAL; + break; + } + } else { + /* Search for an unused domain identifier. */ + for ( ; ; ) + { + spin_lock(&domnr_lock); + /* Wrap the roving counter when we reach first special value. */ + if ( (dom = ++domnr) == DOMID_SELF ) + dom = domnr = 1; + spin_unlock(&domnr_lock); + + if ( (d = find_domain_by_id(dom)) == NULL ) + break; + put_domain(d); + } + } +#endif + long do_dom0_op(dom0_op_t *u_dom0_op) { long ret = 0; @@ -101,25 +193,24 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_CREATEDOMAIN: { struct domain *d; - static domid_t domnr = 0; - static spinlock_t domnr_lock = SPIN_LOCK_UNLOCKED; unsigned int pro; domid_t dom; ret = -ENOMEM; - /* Search for an unused domain identifier. */ - for ( ; ; ) + dom = op->u.createdomain.domain; + if ( 0 < dom && dom < DOMID_SELF ) { - spin_lock(&domnr_lock); - /* Wrap the roving counter when we reach first special value. */ - if ( (dom = ++domnr) == DOMID_SELF ) - dom = domnr = 1; - spin_unlock(&domnr_lock); - - if ( (d = find_domain_by_id(dom)) == NULL ) + if ( !is_free_domid(dom) ) + { + ret = -EINVAL; break; - put_domain(d); + } + } + else + { + ret = allocate_domid(&dom); + if ( ret ) break; } if ( op->u.createdomain.cpu == -1 ) diff --git a/xen/include/hypervisor-ifs/dom0_ops.h b/xen/include/hypervisor-ifs/dom0_ops.h index 9cb5656b3e..502c14744d 100644 --- a/xen/include/hypervisor-ifs/dom0_ops.h +++ b/xen/include/hypervisor-ifs/dom0_ops.h @@ -55,8 +55,10 @@ typedef struct { u8 name[MAX_DOMAIN_NAME]; /* 8 */ u32 cpu; /* 24 */ u32 __pad; /* 28 */ - /* OUT parameters. */ + /* IN/OUT parameters. */ + /* If 0, domain is allocated. If non-zero use it unless in use. */ domid_t domain; /* 32 */ + /* OUT parameters. */ } PACKED dom0_createdomain_t; /* 36 bytes */ #define DOM0_DESTROYDOMAIN 9 -- 2.30.2